#include <iostream>
#include <string>
#include <memory>

//建造者模式
//电脑类
class Computer
{
public:
    Computer() {}

    void setBoard(const std::string& board)
    {
        _board = board;
    }
    void setDisplay(const std::string& display)
    {
        _display = display;
    }
    //纯虚函数接口
    virtual void setOs() = 0;
    //电脑配制显示
    void showParamaters()
    {
        std::string param = "computer paramater:\n";
        param += "\tBoard:" + _board + '\n';
        param += "\tDisplay:" + _display + '\n';
        param += "\tOS:" + _os + '\n';
        std::cout << param << std::endl;
    }

protected:
    std::string _board;
    std::string _display;
    std::string _os;
};

//电脑派生类
class HpBook : public Computer
{
public:
    void setOs() override
    {
        _os = "Windows x86-64";
    }
};

//抽象电脑商建造者类
class Builder
{
public:
    virtual void buildeBoard(const std::string& board) = 0; //建造主板
    virtual void buildeDisplay(const std::string& display) = 0; //建造显示器
    virtual void buildeOs() = 0; //操作系统
    virtual std::shared_ptr<Computer> buildeComputer() = 0;
};
//惠普电脑商建造者：制造电脑部件
class HpBuilder : public Builder
{
public:
    void buildeBoard(const std::string& board) override
    {
        _computer->setBoard(board); //电脑主板
    }
    void buildeDisplay(const std::string& display) override
    {
        _computer->setDisplay(display); //电脑显示器
    }
    void buildeOs() override
    {
        _computer->setOs();//操作系统
    }

    std::shared_ptr<Computer> buildeComputer() override 
    {
        return _computer;
    }
private:
    std::shared_ptr<Computer> _computer;
};

//指挥者
class Director
{
public:
    Director(Builder* builder)
        :_builder(builder)
        {}
    //指挥建造顺序
    void construct(const std::string& board, const std::string& display)
    {
        _builder->buildeBoard(board);
        _builder->buildeDisplay(display);
        _builder->buildeOs();
    }

private:
    std::shared_ptr<Builder> _builder;
};

int main()
{
    //建造者，使用多态
    Builder* builder = new HpBuilder();
    //指挥者
    Director director(builder);
    //指挥建造
    director.construct("小明主板","大黄显示器");
    //生产电脑
    std::shared_ptr<Computer> computer = builder->buildeComputer();
    //显示电脑信息
    computer->showParamaters();

    return 0;
}